function p(casetoken){
    return defun.parsecase(casetoken,"",{},"none");
}
describe("defun.parsecase",function(){
    it("basic type",function(){
        expect(p("'hello'")).toEqual(["hello"]);
        expect(p("true")).toEqual([true]);
        expect(p("false")).toEqual([false]);
        var emptyObj=p("[]")[0];
        expect(emptyObj.value([])).toEqual(true);
        expect(p("123")).toEqual([123]);
        expect(p("null")).toEqual([null]);
    }); 
    it("多个参数",function(){
        expect(p("1,null,2,true")).toEqual([1,null,2,true]);
    });
    it("变量绑定",function(){
        expect(p("x")).toEqual([{type:"symbal",value:"x"}]);
    });
    it("数组解构",function(){
        var arr = p("1 ,(1:xs)");
        var tmp = arr[1].value[0];
        var tmp2 = arr[1].value[1];
        expect(tmp).toEqual(1);
        expect(tmp2).toEqual({type:"symbal",value:"xs"});
    });
    it("数组嵌套",function(){
        var b = p("(1:(11:[]):'))(()')");
        var t1 = b[0].value[1].value[0];
        var t2 = b[0].value[2];
        expect(t1).toEqual(11);
        expect(t2).toEqual("))(()");
    });
    it("解构整个数组",function(){
        var t = p("@all(x:xs)");
        var t1 = t[0].all;
        expect(t1).toEqual({ type: 'symbal', value: 'all' });
    });
    it("对象解构",function(){
        var tmp = p("{name:'d}}iqye',age:24}");
        var t = tmp[0].value[0][0];
        var t1 = tmp[0].value[0][1];
        var tt = tmp[0].value[1][0];
        var tt1 = tmp[0].value[1][1];
        expect(t).toEqual({type:"symbal",value:"name"});
        expect(t1).toEqual("d}}iqye");
        expect(tt).toEqual({type:"symbal",value:"age"});
        expect(tt1).toEqual(24);
    });
    it("对象嵌套",function(){
        var t = p("{a:{'name':'diqye'},b:199}");
        var t1 = t[0].value;
        var t2 = t1[0][1].value;
        var t3 = t2[0][1];
        var t4 = t1[1][1];
        expect(t3).toEqual('diqye');
        expect(t4).toEqual(199);
    });
    it("解构所有对象",function(){
        var t = p("{a:@aall{'name':'diqye'},b:199}");
        var t1 = t[0].value[0][1].all;
        expect(t1).toEqual({type:"symbal",value:"aall"});
    });
    it("问号函数",function(){
        var case1 = p("x?array");
        var t1 = case1[0].qfn;
        expect(t1).toEqual("array");
    });

});
describe("defun",function(){
    function identity(a){return a}
    it("basic",function(){
        var fn = defun({
            "777":777,
            "1,'hello'":"hello-1",
            "1,2":function(){return "__";}
        });
        expect(fn(777)).toEqual(777);
        expect(fn(1,2)).toEqual("__");
    });
    it("忽略参数",function(){
        var fn = defun({
            "a":identity,
            "_,b":identity,
            "_,_,_":"three arg"
        });
        expect(fn("hi")).toEqual("hi");
        expect(fn("hi","who")).toEqual("who");
        expect(fn("hi","who","")).toEqual("three arg");
    });
    it("数组模式匹配",function(){
        var fn = defun({
            "[]":true,
            "null,(x:xs)":function(x,xs){return [x,xs]},
            "'xx',(x:2:y:[])":function(x,y){return [x,y]},
            "1,(1:2:3:x)":function(x){return x},
            "2,(_:_)":2,
            "3,(arr)":identity,
            "_,_,_":"three arg"
        });
        expect(fn([])).toEqual(true);
        expect(fn(null,[1,2,4])).toEqual([1,[2,4]]);
        expect(fn(undefined,[1,2,4])).toEqual([1,[2,4]]);
        expect(fn("xx",[1,2,4])).toEqual([1,4]);
        expect(fn(1,[1,2,3])).toEqual([]);
        expect(fn(1,[1,2,3,4])).toEqual([4]);
        expect(fn(1,[1,2])).toEqual(undefined);
        expect(fn(2,[1,2])).toEqual(2);
        expect(fn(2,[1,2,3,4,5])).toEqual(2);
        expect(fn(3,[1,2,3,4,5])).toEqual([1,2,3,4,5]);
    });
    it("数组嵌套",function(){
        var fn = defun({
            "[]":[],
            "(x:[])":function(x){return x},
            "(1:(11:y:ys):[])":function(y,ys){return [y,ys]},
            "(x:y:[])":function(x,y){return [x,y]},
            "(10:((x:y:[]):100:[]):11:[])":function(x,y){return [x,y]}
        });
        expect(fn([])).toEqual([]);
        expect(fn([1])).toEqual(1);
        expect(fn([1,2])).toEqual([1,2]);
        expect(fn([1,[11,12,13,14]])).toEqual([12,[13,14]]);
        expect(fn([10,[[5,50],100],11])).toEqual([5,50]);
    });
    it("解构所有数组",function(){
        var fn = defun({
            "(1:(@all(1:[])):[])":identity
        });
        expect(fn([1,[1]])).toEqual([1]);
    });
    it("字符串解构",function(){
        var fn =defun({
            "('a':'b':xs)":function(xs){return xs}
        });
        expect(fn("abcdefg")).toEqual("cdefg");
    });
    it("对象解构",function(){
        var fn=defun({
            "{a:1,b:2,c:3}":0,
            "{a:1,b:2}":1,
            "{a:_,b:2}":2,
            "{a,b:'b'}":function(a,b){return [a,4]},
            "{a,b}":function(a,b){return [a,b]}
        });
        expect(fn({a:1,b:2,c:3})).toEqual(0);
        expect(fn({a:1,b:2,c:4})).toEqual(1);
        expect(fn({a:2,b:2,c:3})).toEqual(2);
        expect(fn({a:{aa:1},b:2,c:3})).toEqual(2);
        expect(fn({a:{aa:1},b:3})).toEqual([{aa:1},3]);
        expect(fn({a:{aa:1},b:'b'})).toEqual([{aa:1},4]);
    });
    it("对象嵌套",function(){
        var fn=defun({
            "{a:{aa:11},b:2}":1,
            "{a:{aa:aa},b:2}":function(aa){return aa}
        });
        expect(fn({a:{aa:11},b:2})).toEqual(1);
        expect(fn({a:{aa:12},b:2})).toEqual(12);
    });
    it("对象数组嵌套",function(){
        var fn=defun({
            "{a:(1:2:3:[]),b:2}":1,
            "(1:2:{a:1,b:2}:[])":2
        });
        expect(fn({a:[1,2,3],b:2})).toEqual(1);
        expect(fn([1,2,{a:1,b:2}])).toEqual(2);
    });
    it("@all object",function(){
        var fn=defun({
            "@all{a:1}":identity
        });
        expect(fn({a:1,b:2})).toEqual({a:1,b:2});
    });
    it("问号函数匹配",function(){
        function diqye(o){
            if(o == null) return false;
            return o.type == "diqye";
        }
        defun.globalScope.test=function(a){
            return a == "test";
        }
        var fn=defun({
            "x?diqye":"diqye",
            "x?test":"test",
            "(x?diqye:xs)":function(x,xs){return ['diqye',x,xs]},
            "(x:xs)":function(x,xs){return [x,xs]},
            "x?array":"array"//array是 内置在globalScope里面的
        },{
            diqye:diqye
        });
        expect(fn([])).toEqual("array");
        expect(fn("test")).toEqual("test");
        expect(fn({type:"diqye"})).toEqual("diqye");
        expect(fn([1,2])).toEqual([1,[2]]);
        expect(fn([{type:"diqye"},2])).toEqual(['diqye',{type:'diqye'},[2]]);
    });
    it("空对象",function(){
        var fn = defun({
            "{}":1
        });
        expect(fn({})).toEqual(1);
    });
    it("else",function(){
        var fn = defun({
            "x":1,
            "x,y":2,
            "else":"else"
        });
        var fn2 = defun({"else":function(a,b){return [a,b]}});
        expect(fn(1)).toEqual(1);
        expect(fn(1,2)).toEqual(2);
        expect(fn(1,2,3)).toEqual("else");
        expect(fn(1,2,3,4)).toEqual("else");
        expect(fn2(1,2)).toEqual([1,2]);
    });
});
describe("?function",function(){
    it("?function test",function(){
        var fn = defun({
            "{}":"empty object",
            "[]":"empty array",
            "x?object":"object",
            "x?array":"array",
            "x?string":"string",
            "x?number":"number",
            "x?date":"date"
        });
        expect(fn({})).toEqual("empty object");
        expect(fn([])).toEqual("empty array");
        expect(fn({a:1})).toEqual("object");
        expect(fn([1])).toEqual("array");
        expect(fn('str')).toEqual("string");
        expect(fn(111)).toEqual("number");
        expect(fn(new Date())).toEqual("date");
    });
});
